﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SharpSoft.Maths
{
    /// <summary>
    /// 方队处理工具
    /// </summary>
    public class SquareTeamHepler
    {
        /// <summary>
        /// 根据基准点查找方队中的区域
        /// </summary>
        /// <param name="basePoint">基准点，从基准点向周围辐射查找</param>
        /// <param name="filter">过滤方法</param>
        public static IntVector2[] FindRegion(IntVector2 maxRegionSize, IntVector2 basePoint, Func<IntVector2, bool> filter)
        {
            bool?[,] stateBuf = new bool?[maxRegionSize.X, maxRegionSize.Y];//记录各点的状态false表示已匹配失败，null为未匹配，true为匹配成功

            List<IntVector2> regions = new List<IntVector2>();//记录结果
            List<IntVector2> path = new List<IntVector2>();//记录查询路径
            path.Add(basePoint);

            Func<IntVector2, bool?> getState = (p) =>
            {
                if (p.X < 0 || p.Y < 0 || p.X >= maxRegionSize.X || p.Y >= maxRegionSize.Y)
                {//超出边界
                    return false;
                }
                return stateBuf[p.X, p.Y];
            };
            while (path.Count > 0)
            {
                var p = path[path.Count - 1];
                var state = getState(p);
                if (state == null)
                {//该点没有匹配过
                    var matched = filter(p);
                    if (matched)
                    {//该点匹配
                        regions.Add(p);
                        stateBuf[p.X, p.Y] = true;
                    }
                    else
                    {//该点不匹配 
                        stateBuf[p.X, p.Y] = false;
                    }
                }
                else
                {//已经匹配过
                    if (state.Value)
                    {//该点是匹配的
                        var p1 = new IntVector2(p.X + 1, p.Y);
                        if (getState(p1) == null)
                        {//右边未匹配
                            path.Add(p1);
                            continue;
                        }
                        p1 = new IntVector2(p.X - 1, p.Y);
                        if (getState(p1) == null)
                        {//左边未匹配
                            path.Add(p1);
                            continue;
                        }
                        p1 = new IntVector2(p.X, p.Y - 1);
                        if (getState(p1) == null)
                        {//上边未匹配
                            path.Add(p1);
                            continue;
                        }
                        p1 = new IntVector2(p.X, p.Y + 1);
                        if (getState(p1) == null)
                        {//下边未匹配
                            path.Add(p1);
                            continue;
                        }
                        //周边四个点都匹配过，从路径移除这个点
                        path.RemoveAt(path.Count - 1);
                    }
                    else
                    {//该点不匹配，从路径移除这个点
                        path.RemoveAt(path.Count - 1);
                    }
                }

            }

            return regions.ToArray();
        }
    }
}
